home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / XPK / Source / shell / xBench.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-20  |  11.1 KB  |  476 lines

  1. #define NAME     "xBench"
  2. #define VERSION  "2"
  3. #define REVISION "5"
  4.  
  5. /* Programmheader
  6.  
  7.         Name:           xBench
  8.         Author:         SDI (before 1.1 Urban Dominik Müller)
  9.         Distribution:   PD
  10.         Description:    xpk benchmark utility
  11.         Compileropts:   -gM
  12.         Linkeropts:     -l xpkmaster amiga -gsi
  13.  
  14.  1.1   29.11.96 : added version string
  15.  1.2   20.12.96 : added output telling the caller mechanism
  16.  2.0   31.03.97 : now OS 2.0 and up only, rewritten, now an utility to
  17.         allow users making benchmarks
  18.  2.1   01.04.97 : fixed some errors
  19.  2.2   23.04.97 : fixed time calculation
  20.  2.3   10.05.97 : added ALL flag, use with care!
  21.  2.4   08.06.97 : added forgotten TAG_DONE
  22.  2.5   20.06.97 : added Pattern Matching
  23. */
  24.  
  25. #include <pragma/dos_lib.h>
  26. #include <pragma/timer_lib.h>
  27. #include <pragma/xpkmaster_lib.h>
  28. #include <pragma/exec_lib.h>
  29. #include <exec/memory.h>
  30. #include <exec/devices.h>
  31. #include "SDI_defines.h"
  32. #define SDI_TO_ANSI
  33. #include "SDI_ASM_STD_protos.h"
  34.  
  35. /* METHOD's are:
  36.  <mode - upper case, 4 chars>[.<mode - dec number>]
  37. */
  38.  
  39. #define PARAMS  "FILENAME/A,PASSWORD/K,METHOD/M,TEST/S,ALL/S,SAVE/K"
  40. #define HEADER  "Type  Num Version Password  CSize  CTime    CSpd  USize  UTime    USpd Rate\n"
  41. #define DATATXT "%s: %3ld %2ld.%ld\t  %8.8s %6ld %3ld.%02ld %7ld %6ld %3ld.%02ld %7ld %2ld.%ld\n"
  42. #define SIZEERR "%s: FileSize false after decrunching %ld != %ld\n"
  43. #define BUFERR  "%s: Decrunched buffer different to source!\n"
  44.  
  45. struct Args {
  46.   STRPTR        filename;
  47.   STRPTR        password;
  48.   STRPTR *      method;
  49.   ULONG        test;
  50.   ULONG        all;
  51.   STRPTR    save;
  52. };
  53.  
  54. struct TestData {
  55.   STRPTR    sbuf;
  56.   ULONG        sbufsize;
  57.   STRPTR    pbuf;
  58.   ULONG        pbufsize;
  59.   STRPTR    ubuf;
  60.   ULONG        ubufsize;
  61.   STRPTR    password;
  62.   ULONG        test;
  63.   ULONG        all;
  64.   STRPTR    save;
  65.   struct FileInfoBlock *fib;
  66.   struct XpkPackerInfo *pinfo;
  67.   struct XpkMode *minfo;
  68. };
  69.  
  70. struct BenchData {
  71.   STRPTR    method;
  72.   ULONG        mode;
  73.   ULONG        version;
  74.   ULONG        revision;
  75.   STRPTR    password;
  76.   ULONG        CSize;
  77.   ULONG        CTime;
  78.   ULONG        CTime100;
  79.   ULONG        CSpd;
  80.   ULONG        USize;
  81.   ULONG        UTime;
  82.   ULONG        UTime100;
  83.   ULONG        USpd;
  84.   ULONG        Rate;
  85.   ULONG        Rate10;
  86. };
  87.  
  88. struct DosLibrary *     DOSBase;
  89. struct Library *        XpkBase;
  90. struct Library *    TimerBase;
  91.  
  92. ULONG DoIt(STRPTR name, struct TestData *tdat, STRPTR *method);
  93. LONG GetPackData(struct BenchData *b, struct TestData *t, STRPTR pwd);
  94. void DoTest(struct TestData *data, STRPTR method, ULONG mode);
  95. void ScanMethods(struct TestData *data, STRPTR method);
  96. void ScanPackers(struct TestData *data);
  97.  
  98. #define PATHNAME_SIZE 256
  99.  
  100. ULONG start(void) /* not named main, to get error with startup code ! */
  101. {
  102.  ULONG                  error   = RETURN_FAIL;
  103.  struct DosLibrary *    dosbase;
  104.  struct Process *       task;
  105.  
  106.  /* test for WB and reply startup-message */
  107.  if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  108.  {
  109.   WaitPort(&task->pr_MsgPort);
  110.   Forbid();
  111.   ReplyMsg(GetMsg(&task->pr_MsgPort));
  112.   return RETURN_FAIL;
  113.  }
  114.  
  115.  if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  116.  {
  117.   struct Library *xpkbase;
  118.  
  119.   DOSBase = dosbase; /* set global base */
  120.   if((xpkbase = OpenLibrary("xpkmaster.library", 4)))
  121.   {
  122.    struct RDArgs *rda;
  123.    struct Args args = {0, 0, 0, 0};
  124.  
  125.    XpkBase = xpkbase;
  126.    if((rda = ReadArgs(PARAMS, (LONG *) &args, 0)))
  127.    {
  128.     struct FileInfoBlock *fib;
  129.  
  130.     if((fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)))
  131.     {
  132.      struct AnchorPath *APath;
  133.      struct TestData tdat;
  134.      ULONG retval;
  135.  
  136.      tdat.password = args.password;
  137.      tdat.test = args.test;
  138.      tdat.all = args.all;
  139.      tdat.save = args.save;
  140.      tdat.fib = fib;
  141.  
  142.      if((APath = (struct AnchorPath *) AllocMem(sizeof(struct AnchorPath)+
  143.      PATHNAME_SIZE, MEMF_PUBLIC|MEMF_CLEAR)))
  144.      {
  145.       APath->ap_BreakBits = SIGBREAKF_CTRL_C;
  146.       APath->ap_Strlen = PATHNAME_SIZE;
  147.  
  148.       for(retval = MatchFirst(args.filename, APath); !retval; retval = MatchNext(APath))
  149.       {
  150.        if(APath->ap_Flags & APF_DIDDIR)
  151.         APath->ap_Flags &= ~APF_DIDDIR;
  152.        else if(APath->ap_Info.fib_DirEntryType > 0)
  153.        {
  154. /*        if(args.deep)
  155.          APath->ap_Flags |= APF_DODIR; */
  156.        }
  157.        else if((error = DoIt(APath->ap_Buf, &tdat, args.method)))
  158.          break;
  159.       }
  160.       MatchEnd(APath);
  161.       FreeMem(APath, sizeof(struct AnchorPath)+PATHNAME_SIZE);
  162.      }
  163.      FreeDosObject(DOS_FIB, fib);
  164.     }
  165.     FreeArgs(rda);
  166.    }
  167.    CloseLibrary(xpkbase);
  168.   }
  169.   if(error && IoErr()) /* print the error */
  170.    PrintFault(IoErr(), 0);
  171.   CloseLibrary((struct Library *) dosbase);
  172.  }
  173.  
  174.  return error;
  175. }
  176.  
  177. ULONG DoIt(STRPTR name, struct TestData *tdat, STRPTR *method)
  178. {
  179.   ULONG error = RETURN_FAIL;
  180.   ULONG fh;
  181.  
  182.   if((fh = Open(name, MODE_OLDFILE)))
  183.   {
  184.    if(ExamineFH(fh, tdat->fib))
  185.    {
  186.     tdat->sbufsize = tdat->fib->fib_Size;
  187.     tdat->ubufsize = tdat->fib->fib_Size + XPK_MARGIN;
  188.     tdat->pbufsize = tdat->fib->fib_Size + (tdat->fib->fib_Size>>5) + (XPK_MARGIN<<1);
  189.  
  190.     if((tdat->sbuf = (STRPTR) AllocMem(tdat->sbufsize, MEMF_ANY)))
  191.     {
  192.      if((tdat->ubuf = (STRPTR) AllocMem(tdat->ubufsize, MEMF_ANY)))
  193.      {
  194.       if((tdat->pbuf = (STRPTR) AllocMem(tdat->pbufsize, MEMF_ANY)))
  195.       {
  196.        if(Read(fh, tdat->sbuf, tdat->sbufsize) == tdat->sbufsize)
  197.        {
  198.         struct timerequest timerequest = {0};
  199.  
  200.         if(!OpenDevice("timer.device", UNIT_ECLOCK, (struct IORequest *)
  201.         &timerequest, 0))
  202.     {
  203.      TimerBase = &timerequest.tr_node.io_Device->dd_Library;
  204.      if((tdat->pinfo = (struct XpkPackerInfo *)
  205.      XpkAllocObject(XPKOBJ_PACKERINFO, 0)))
  206.      {
  207.       if((tdat->minfo = (struct XpkMode *)
  208.       XpkAllocObject(XPKOBJ_MODE, 0)))
  209.       {
  210.            VPrintf("%s\n" HEADER, &name);
  211.            if(method)
  212.            {
  213.             for(;*method && !CTRL_C; ++method)
  214.             {
  215.          if(!(*method)[0] || !(*method)[1] ||
  216.          !(*method)[2] || !(*method)[3])
  217.           XpkPrintFault(XPKERR_MISSINGLIB, *method); 
  218.          else
  219.          {
  220.           (*method)[0] = toupper((*method)[0]);
  221.           (*method)[1] = toupper((*method)[1]);
  222.           (*method)[2] = toupper((*method)[2]);
  223.           (*method)[3] = toupper((*method)[3]);
  224.           if((*method)[4] == '.')
  225.               {
  226.                (*method)[4] = 0;
  227.                DoTest(tdat, *method, strtoul(*method+5, 0,10));
  228.               }
  229.               else
  230.                ScanMethods(tdat, *method);
  231.              }
  232.             }
  233.            }
  234.            else
  235.             ScanPackers(tdat);
  236.        error = 0;
  237.        XpkFreeObject(XPKOBJ_MODE, tdat->minfo);
  238.       }
  239.       XpkFreeObject(XPKOBJ_PACKERINFO, tdat->pinfo);
  240.      }
  241.      CloseDevice((struct IORequest *) &timerequest);
  242.         }
  243.        }
  244.        FreeMem(tdat->pbuf, tdat->pbufsize);
  245.       }
  246.       FreeMem(tdat->ubuf, tdat->ubufsize);
  247.      }
  248.      FreeMem(tdat->sbuf, tdat->sbufsize);
  249.     }
  250.    }
  251.    Close(fh);
  252.   }
  253.   return error;
  254. }
  255.  
  256. /* These must be defined false, because this is a benchmark tool ! */
  257. static struct TagItem deftags[] = {
  258. { XPK_Preferences, FALSE},
  259. { XPK_UseXfdMaster, FALSE},
  260. { XPK_UseExternals, FALSE},
  261. { XPK_PassRequest, FALSE},
  262. { XPK_ChunkReport, FALSE},
  263. { TAG_DONE, 0},
  264. };
  265.  
  266. LONG GetPackData(struct BenchData *b, struct TestData *t, STRPTR pwd)
  267. {
  268.   struct EClockVal eval1, eval2;
  269.   LONG err, d;
  270.   ULONG freq;
  271.  
  272.   Forbid();
  273.   freq = ReadEClock(&eval1);
  274.   err = XpkPackTags(
  275.     XPK_InBuf,    t->sbuf,
  276.     XPK_InLen,    t->sbufsize,
  277.     XPK_OutBuf,    t->pbuf,
  278.     XPK_OutBufLen,    t->pbufsize,
  279.     XPK_GetOutLen,    &(b->CSize),
  280.     pwd ? XPK_Password : TAG_IGNORE,    pwd,
  281.     XPK_PackMethod,    b->method,
  282.     XPK_PackMode,    b->mode,
  283.     TAG_MORE,    deftags);
  284.   ReadEClock(&eval2);
  285.   Permit();
  286.   b->CTime = eval2.ev_lo - eval1.ev_lo;
  287.   if(err)
  288.     return err;
  289.   Forbid();
  290.   ReadEClock(&eval1);
  291.   err = XpkUnpackTags(
  292.     XPK_InBuf,    t->pbuf,
  293.     XPK_InLen,    t->pbufsize,
  294.     XPK_OutBuf,    t->ubuf,
  295.     XPK_OutBufLen,    t->ubufsize,
  296.     XPK_GetOutLen,    &d,
  297.     pwd ? XPK_Password : TAG_IGNORE, pwd,
  298.     TAG_MORE,    deftags);
  299.   ReadEClock(&eval2);
  300.   Permit();
  301.   if(err)
  302.     return err;
  303.   b->UTime = eval2.ev_lo - eval1.ev_lo;
  304.  
  305.   if(d != t->sbufsize)
  306.   {
  307.     Printf(SIZEERR, b->method, t->sbufsize, t); return 1;
  308.   }
  309.   if(t->test)
  310.   {
  311.     for(; d && t->sbuf[d-1] == t->ubuf[d-1]; --d)
  312.       ;
  313.     memset(t->ubuf, 0, t->ubufsize);
  314.     if(d)
  315.     {
  316.       VPrintf(BUFERR, &b->method); return 1;
  317.     }
  318.   }
  319.  
  320.   if(t->save)
  321.   {
  322.     ULONG lock, fh;
  323.  
  324.     if((lock = Lock(t->save, SHARED_LOCK)))
  325.     {
  326.       lock = CurrentDir(lock);
  327.       if(Examine(lock, t->fib) && t->fib->fib_DirEntryType > 0)
  328.       {
  329.         UBYTE data[10];
  330.  
  331.         sprintf(data, "%.4s.%03ld", b->method, b->mode);
  332.         if((fh = Open(data, MODE_NEWFILE)))
  333.         {
  334.           Write(fh, t->pbuf, b->CSize);
  335.           Close(fh);
  336.         }
  337.       }
  338.       UnLock(CurrentDir(lock));
  339.     }
  340.   }
  341.  
  342.   if((d = 1000 - ((1000 * b->CSize)/b->USize)) < 0)
  343.     d = 0;
  344.  
  345.   b->Rate   = d/10;
  346.   b->Rate10 = d % 10;
  347.  
  348.   b->CTime100 = (100 * (b->CTime % freq)) / freq;
  349.   b->UTime100 = (100 * (b->UTime % freq)) / freq;
  350.   b->CTime /= freq;
  351.   b->UTime /= freq;
  352.  
  353.   if(!b->CTime && !b->CTime100)
  354.     b->CTime100 = 1;
  355.   if(!b->UTime && !b->UTime100)
  356.     b->UTime100 = 1;
  357.  
  358.   b->CSpd = ((100*b->USize) / ((100 * b->CTime) + b->CTime100));
  359.   b->USpd = ((100*b->USize) / ((100 * b->UTime) + b->UTime100));
  360.   return 0;
  361. }
  362.  
  363. void DoTest(struct TestData *t, STRPTR method, ULONG mode)
  364. {
  365.   struct BenchData b;
  366.   struct Library *xbase;
  367.   UBYTE libname[] = "compressors/xpk____.library";
  368.  
  369.   LONG err;
  370.  
  371.   CopyMem(method, libname+15, 4);
  372.  
  373.   if(!(xbase = OpenLibrary(libname, 0)))
  374.   {
  375.     XpkPrintFault(XPKERR_MISSINGLIB, method);
  376.     return;
  377.   }
  378.   b.version = xbase->lib_Version;
  379.   b.revision = xbase->lib_Revision;
  380.   CloseLibrary(xbase);
  381.  
  382.   libname[19] = 0;
  383.   b.method = libname + 15;
  384.   if((b.mode = mode) > 100)
  385.     b.mode = 100;
  386.   b.USize = t->sbufsize;
  387.  
  388.   if((err = XpkQueryTags(
  389.     XPK_PackerQuery,    t->pinfo,
  390.     XPK_PackMethod,        b.method,
  391.     TAG_MORE,        deftags,
  392.     TAG_DONE)))
  393.   {
  394.     XpkPrintFault(err, b.method);
  395.     return;
  396.   }
  397.  
  398.   if((t->pinfo->xpi_Flags & XPKIF_NEEDPASSWD) && !t->password)
  399.     return;
  400.  
  401.   if((t->pinfo->xpi_Flags & XPKIF_ENCRYPTION) && t->password)
  402.   {
  403.     b.password = t->password;
  404.     if((err = GetPackData(&b, t, t->password)))
  405.     {
  406.       if(err < 0)
  407.         XpkPrintFault(err, b.method);
  408.       return;
  409.     }
  410.     else
  411.       VPrintf(DATATXT, &b);
  412.   }
  413.   if(!(t->pinfo->xpi_Flags & XPKIF_NEEDPASSWD))
  414.   {
  415.     b.password = "";
  416.     if((err = GetPackData(&b, t, 0)))
  417.     {
  418.       if(err < 0)
  419.         XpkPrintFault(err, b.method);
  420.       return;
  421.     }
  422.     else
  423.       VPrintf(DATATXT, &b);
  424.   }
  425. }
  426.  
  427. void ScanPackers(struct TestData *t)
  428. {
  429.   LONG err, i;
  430.   struct XpkPackerList *pl;
  431.  
  432.   if((pl = (struct XpkPackerList *) XpkAllocObject(XPKOBJ_PACKERLIST, 0)))
  433.   {
  434.     if((err = XpkQueryTags(
  435.     XPK_PackersQuery,    pl,
  436.     TAG_MORE,        deftags,
  437.     TAG_DONE)))
  438.     {
  439.       XpkPrintFault(err, 0); return;
  440.     }
  441.  
  442.     for(i = 0; i < pl->xpl_NumPackers && !CTRL_C; i++)
  443.       ScanMethods(t, pl->xpl_Packer[i]);
  444.  
  445.     XpkFreeObject(XPKOBJ_PACKERLIST, pl);
  446.   }
  447. }
  448.  
  449. void ScanMethods(struct TestData *t, STRPTR method)
  450. {
  451.   LONG err;
  452.   ULONG mode;
  453.  
  454.   if(t->all)
  455.   {
  456.     for(mode = 0; mode <= 100 && !CTRL_C; ++mode)
  457.      DoTest(t, method, mode);
  458.   }
  459.   else
  460.   {
  461.     for(mode = 0; mode < 100 && !CTRL_C; mode = t->minfo->xm_Upto + 1)
  462.     {
  463.       if((err = XpkQueryTags(
  464.     XPK_ModeQuery,    t->minfo,
  465.     XPK_PackMethod,    method,
  466.     XPK_PackMode,     mode,
  467.     TAG_MORE,    deftags)))
  468.       {
  469.         XpkPrintFault(err, method); return;
  470.       }
  471.       DoTest(t, method, t->minfo->xm_Upto);
  472.     }
  473.   }
  474. }
  475.  
  476.